home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1995 November / Macworld Nov ’95.toast / Developers / BoxMaker++ / µZak ƒ / µZakshell.cp < prev    next >
Encoding:
Text File  |  1995-06-14  |  9.5 KB  |  436 lines  |  [TEXT/KAHL]

  1. #include <Types.h>
  2. #include <Memory.h>
  3. #include <QuickDraw.h>
  4. #include <OSUtils.h>
  5. #include <ToolUtils.h>
  6. #include <Menus.h>
  7. #include <Packages.h>
  8. #include <Traps.h>
  9. #include <Files.h>
  10. #include <Aliases.h>
  11. #include <AppleEvents.h>
  12. #include <GestaltEqu.h>
  13. #include <Processes.h>
  14. #include <Fonts.h>
  15. #include <OSEvents.h>
  16. #include <Resources.h>
  17. #include <Desk.h>
  18. #include <Movies.h>
  19. #include <Folders.h>
  20.  
  21. #include "standardgetfile.h"
  22. #include "boxmakergetfile.h"
  23.  
  24. #include "boxmaker constants.h"
  25. #include "boxmaker.h"
  26. #include "preferences.cp"
  27. #include "queue.cp"
  28.  
  29. #include "µZak error messages.h"
  30. #include "µZakshell.h"
  31.  
  32. #pragma template_access public
  33.  
  34. void main();
  35.  
  36. void main()
  37. {
  38.     muZaksettings defaultSettings =
  39.     {
  40.         iShowPreferences,
  41.         false,                // do not requeue
  42.         false,                // do not shuffle
  43.         VolumeNormal        // normal volume
  44.     };
  45.     StringHandle prefsFileHandle = GetString( 128);
  46.     Handle configHandle = Get1Resource( 'cnfg', 128);
  47.     const long queueLength = (configHandle == 0) ? 50 : **(long **)configHandle;
  48.     muZakshell it( *(Str255 *)*prefsFileHandle, defaultSettings, queueLength);
  49.     it.run();
  50.     //
  51.     // For now, do not free the memory allocated properly
  52.     // (quitting is faster this way).
  53.     //    ReleaseResource( (Handle)prefsFileHandle);
  54.     //    ReleaseResource( configHandle);
  55.     //
  56. }
  57.  
  58. muZakshell::muZakshell( Str255 prefsFileName,
  59.     muZaksettings &defaultsettings, unsigned long queueLength)
  60.     : boxmaker( 3000)
  61.     , muZakPrefs( prefsFileName, defaultsettings)
  62.     , alias_queue( queueLength)
  63. {
  64.     //
  65.     // Check for presence of QuickTime:
  66.     //
  67.     long response;
  68.     OSErr result = Gestalt( gestaltQuickTime, &response);
  69.     
  70.     if( (result != noErr) || (response == 0))
  71.     {
  72.         //
  73.         // QuickTime not present => display alert saying so, and exit
  74.         //
  75.         ErrorAlertQuit( (result != noErr) ? result : response, kNeedQuickTimeError);
  76.     }
  77.     result = EnterMovies();
  78.     if( result != noErr)
  79.     {
  80.         ErrorAlertQuit( result, kEnterMoviesFailedError);
  81.     }
  82.     theMovie = 0;
  83.     theAlias = 0;
  84.     SetButtons();
  85.     SetRequeueButton();
  86.     SetShuffleButton();
  87.     SetVolumePopup();
  88.  
  89.     switch( wie_van_de_drie)
  90.     {
  91.         case iShowPreferences:
  92.             ShowPreferences();
  93.             //
  94.             // For nice feedback when scores of files are dropped
  95.             // on the shell we draw the dialog immediately.
  96.             //
  97.             DrawDialog( gMainDialog);
  98.             SetPort( gMainDialog);
  99.             ValidRect( &thePort->portRect);
  100.             break;
  101.             
  102.         case  iHideOnLaunch:
  103.             //
  104.             // First item in the Applications menu is 'Hide <current app>'
  105.             //
  106.             SystemMenu( 0xBF970001);
  107.             break;
  108.  
  109.         case iNeither:
  110.             ;
  111.     }
  112.     qd.randSeed = TickCount();    // for true shuffle
  113. }
  114.  
  115. muZakshell::~muZakshell()
  116. {
  117.     if( theMovie != 0)
  118.     {
  119.         StopCurrentMovie();
  120.     }
  121.     //
  122.     // Should dispose of any aliases in the queue or in 'theAlias', here.
  123.     // (see the handling of 'iCancelQueue' how to do this)
  124.     //
  125.     // This is not done since we will ExitToShell real soon now, and
  126.     // this will free the memory, anyway.
  127.     //
  128. }
  129.  
  130. void muZakshell::OpenDoc( Boolean opening)
  131. {
  132.     if( opening)
  133.     {
  134.         //
  135.         // Add the movie to the list of movies to be played.
  136.         // We do not check for errors. If the queue is full,
  137.         // the item is discarded.
  138.         //
  139.         if( !isFull())
  140.         {
  141.             AliasHandle newAlias;
  142.             if( NewAliasMinimal( &theFSSpec, &newAlias) == noErr)
  143.             {
  144.                 Add( newAlias);
  145.                 updateNumber();
  146.             }
  147.         }
  148.     }
  149. }
  150.  
  151. void muZakshell::HandleDialogEvent( short itemHit, DialogPtr theDialog)
  152. {
  153.     switch( itemHit)
  154.     {
  155.         case iShowPreferences:
  156.         case iHideOnLaunch:
  157.         case iNeither:
  158.             wie_van_de_drie = itemHit;
  159.             SetButtons();
  160.             break;
  161.         
  162.         case iRequeue:
  163.             requeue_after_playing = !requeue_after_playing;
  164.             SetRequeueButton();
  165.             break;
  166.     
  167.         case iShuffle:
  168.             shuffle = !shuffle;
  169.             SetShuffleButton();
  170.             break;
  171.  
  172.         case iVolume:
  173.             {
  174.                 short    iType;
  175.                 Handle    iHandle;
  176.                 Rect    iRect;
  177.                 GetDialogItem( gMainDialog, iVolume, &iType, &iHandle, &iRect);
  178.                 volume = (soundVolume)GetControlValue( (ControlHandle)iHandle);
  179.                 
  180.                 if( theMovie != 0)
  181.                 {
  182.                     SetMovieVolume( theMovie, theVolumes[ volume]);
  183.                 }
  184.             }
  185.             break;
  186.  
  187.         case iCancelCurrent:
  188.             if( theMovie != 0)
  189.             {
  190.                 StopCurrentMovie();
  191.             }
  192.             break;
  193.  
  194.         case iCancelQueue:
  195.             while( !isEmpty())
  196.             {
  197.                 AliasHandle anAlias = Remove();
  198.                 DisposeHandle( (Handle)anAlias);
  199.             }
  200.             updateNumber();
  201.             break;
  202.             
  203.         case iNameOfFile:
  204.         case iQueueLength:
  205.         default:
  206.             ;
  207.     }
  208. }
  209.  
  210. Boolean muZakshell::mayEnterFolder( Boolean opening)
  211. {
  212.     //
  213.     // it doesn't make sense to enter a folder when the alias queue is
  214.     // full, since then any movie file found will be discarded by the
  215.     // OpenDoc handler
  216.     //
  217.     return !isFull();
  218. }
  219.  
  220. Boolean muZakshell::EventloopHook()
  221. {
  222.     Boolean result = false;
  223.     if( theMovie == 0)
  224.     {
  225.         //
  226.         // Is there an item to play?
  227.         //
  228.         if( isEmpty() || (the_status == shell_is_quitting))
  229.         {
  230.             result = true;
  231.         } else {
  232.             //
  233.             // brute force shuffle (will be fairly slow when
  234.             // lots of files are present)
  235.             //
  236.             const int maxNumToSkip = getLength() - 3;
  237.             if( shuffle && (maxNumToSkip > 0))
  238.             {
  239.                 const int numToSkip = Random() % maxNumToSkip;
  240.                 for( int i = 0; i < numToSkip; i++)
  241.                 {
  242.                     Add( Remove());
  243.                 }
  244.             }
  245.             theAlias = Remove();
  246.             updateNumber();
  247.             StartAMovie();
  248.         }
  249.     } else {
  250.         if( IsMovieDone( theMovie) || (the_status == shell_is_quitting))
  251.         {
  252.             StopCurrentMovie( false);
  253.             if( requeue_after_playing && !isFull()
  254.                     && (the_status != shell_is_quitting))
  255.             {
  256.                 Add( theAlias);
  257.                 updateNumber();
  258.             } else {
  259.                 DisposeHandle( (Handle)theAlias);
  260.             }
  261.         } else {
  262.             MoviesTask( theMovie, 0L);
  263.         }
  264.     }
  265.     return result;
  266. }
  267.  
  268. void muZakshell::StartAMovie()
  269. {
  270.     //
  271.     // First resolve the Alias:
  272.     //
  273.     FSSpec theFSSpec;
  274.     Boolean wasChanged;
  275.     const OSErr result = ResolveAlias( 0L, theAlias, &theFSSpec, &wasChanged);
  276.     
  277.     if( result == noErr)
  278.     {
  279.         //
  280.         // Note: we do not have to check whether we are in the background
  281.         // when setting the cursor. The system seems to do that for us.
  282.         //
  283.         CursHandle prisma = GetCursor( watchCursor);
  284.         SetCursor( *prisma);
  285.         ReleaseResource( (Handle)prisma);
  286.         OSErr err = OpenMovieFile( &theFSSpec, &theMovieFile, fsRdPerm);
  287.         long  controllerFlags;
  288.         
  289.         if( (err != noErr) || (GetMoviesError() != noErr))
  290.         {
  291.             ErrorAlert( err, kMovieToolboxError);
  292.         }    
  293.         short theMovieResID = 0;    // want first movie in the file
  294.     
  295.         err = NewMovieFromFile( &theMovie, theMovieFile, &theMovieResID,
  296.                     (StringPtr) 0, newMovieActive, (Boolean *) 0);
  297.     
  298.         if( (err != noErr) || (GetMoviesError() != noErr))
  299.         {
  300.             ErrorAlert( err, kMovieToolboxError);
  301.         }    
  302.         //
  303.         // Disable all non-sound tracks found:
  304.         //
  305.         const long numTracks = GetMovieTrackCount( theMovie);
  306.         unsigned long numSoundTracks = 0;
  307.         //
  308.         // 941130: Thanks to Paul C. Ho of 'All Midi' fame
  309.         // I learnt to count from track 1 (instead of from zero)
  310.         //
  311.         for( int trackNo = 1; trackNo <= numTracks; trackNo++)
  312.         {
  313.             Track theTrack = GetMovieIndTrack( theMovie, trackNo);
  314.             Media theMedia = GetTrackMedia( theTrack);
  315.             OSType mediaType;
  316.             GetMediaHandlerDescription( theMedia, &mediaType, nil, nil);
  317.             //
  318.             // Note: some older sound media have mediaType == 0, but so do some
  319.             // video media => some sound media will not be disabled.
  320.             // Also, my headers aren't up to date, so MusicMediaType isn't defined.
  321.             //
  322.             const Boolean isaSoundMedia =
  323.                 (mediaType == SoundMediaType) || (mediaType == MusicMediaType);
  324.     
  325.             if( isaSoundMedia)
  326.             {
  327.                 numSoundTracks += 1;
  328.             } else {
  329.                 SetTrackEnabled( theTrack, false);
  330.             }
  331.         }
  332.         if( numSoundTracks == 0)
  333.         {
  334.             StopCurrentMovie();
  335.         } else {
  336.             //
  337.             // Change the cover procedures (no longer needed now that we call 'SetMovieBox')
  338.             //            
  339.             const Rect nullRect = {0, 0, 0, 0};
  340.             SetMovieBox( theMovie, &nullRect);
  341.             //
  342.             // Now we can preroll and play the movie
  343.             //
  344.             err = PrerollMovie( theMovie, GetMovieDuration( theMovie), GetMovieRate( theMovie));
  345.             
  346.             if( err != noErr)
  347.             {
  348.                 ErrorAlert( err, kMovieToolboxError);
  349.             }
  350.             //
  351.             // 950516: change volume
  352.             //
  353.             SetMovieVolume( theMovie, theVolumes[ volume]);
  354.             
  355.             StartMovie( theMovie);
  356.             updateName( theFSSpec.name);
  357.         }
  358.         InitCursor();
  359.     }
  360. }
  361.  
  362. void muZakshell::StopCurrentMovie( Boolean dispose_of_alias)
  363. {
  364.     if( theMovie != 0)    // better be safe than sorry
  365.     {
  366.         CloseMovieFile( theMovieFile);
  367.         DisposeMovie( theMovie);
  368.         theMovie = 0;
  369.         updateName( "\p");
  370.         if( dispose_of_alias)
  371.         {
  372.             DisposeHandle( (Handle)theAlias);
  373.             theAlias = 0;    // just for tidyness; a _perfect_ compiler will optimize it away
  374.         }
  375.     }
  376. }
  377.  
  378. void muZakshell::SetButtons()
  379. {
  380.     for( int itemNo = iShowPreferences; itemNo <= iNeither; itemNo++)
  381.     {
  382.         short    iType;
  383.         Handle    iHandle;
  384.         Rect    iRect;
  385.         GetDialogItem( gMainDialog, itemNo, &iType, &iHandle, &iRect);
  386.         SetControlValue( (ControlHandle)iHandle, (itemNo == wie_van_de_drie));    
  387.     }
  388. }
  389.  
  390. void muZakshell::SetRequeueButton()
  391. {
  392.     short    iType;
  393.     Handle    iHandle;
  394.     Rect    iRect;
  395.     GetDialogItem( gMainDialog, iRequeue, &iType, &iHandle, &iRect);
  396.     SetControlValue( (ControlHandle)iHandle, requeue_after_playing);    
  397. }
  398.  
  399. void muZakshell::SetShuffleButton()
  400. {
  401.     short    iType;
  402.     Handle    iHandle;
  403.     Rect    iRect;
  404.     GetDialogItem( gMainDialog, iShuffle, &iType, &iHandle, &iRect);
  405.     SetControlValue( (ControlHandle)iHandle, shuffle);    
  406. }
  407.  
  408. void muZakshell::SetVolumePopup()
  409. {
  410.     short    iType;
  411.     Handle    iHandle;
  412.     Rect    iRect;
  413.     GetDialogItem( gMainDialog, iVolume, &iType, &iHandle, &iRect);
  414.     SetControlValue( (ControlHandle)iHandle, volume);
  415. }
  416.  
  417. void muZakshell::updateName( Str63 theName)
  418. {
  419.     short    iType;
  420.     Handle    iHandle;
  421.     Rect    iRect;
  422.     GetDialogItem( gMainDialog, iNameOfFile, &iType, &iHandle, &iRect);
  423.     SetDialogItemText( iHandle, theName);
  424. }
  425.  
  426. void muZakshell::updateNumber()
  427. {
  428.     short    iType;
  429.     Handle    iHandle;
  430.     Rect    iRect;
  431.     Str15 string;
  432.     NumToString( getLength(), string);
  433.     GetDialogItem( gMainDialog, iQueueLength, &iType, &iHandle, &iRect);
  434.     SetDialogItemText( iHandle, string);
  435. }
  436.